package org.xydpeng.framework.l2cache.support;

import jakarta.annotation.PreDestroy;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.xydpeng.framework.l2cache.message.CacheMessageMulticaster;
import org.xydpeng.framework.l2cache.properties.L2CacheConfigProperties;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * @author xydpeng
 * @version v1.0
 * @date: 2024/6/4
 * @description:
 */
public class RedisCaffeineL2CacheManager implements CacheManager, InitializingBean, DisposableBean {

    private ConcurrentHashMap<String, Cache> cacheMap = new ConcurrentHashMap();
    private volatile Set<String> cacheNames = new HashSet<>();
    private L2CacheConfigProperties l2CacheConfigProperties;
    private CacheProperties cacheProperties;
    private RedisTemplate redisTemplate;
    @Autowired
    @Lazy
    private CacheMessageMulticaster cacheMessageMulticaster;

    public RedisCaffeineL2CacheManager(L2CacheConfigProperties l2CacheConfigProperties,
                                       CacheProperties cacheProperties,
                                       RedisTemplate redisTemplate) {
        this.l2CacheConfigProperties = l2CacheConfigProperties;
        this.cacheProperties = cacheProperties;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public Cache getCache(String name) {
        return cacheMap.computeIfAbsent(name, this::createCache);
    }

    @Override
    public Collection<String> getCacheNames() {
        return this.cacheNames;
    }

    protected Cache createCache(String cacheName) {
        cacheNames.add(cacheName);
        return new RedisCaffeineL2Cache(cacheName, cacheProperties, l2CacheConfigProperties, redisTemplate, cacheMessageMulticaster);
    }

    //@PostConstruct
    @Override
    public void afterPropertiesSet() throws Exception {
        CacheScheduler.scheduledThreadPool = new ScheduledThreadPoolExecutor(l2CacheConfigProperties.getDelayThreads());
    }

    //@PreDestroy
    public void destroy() {
        CacheScheduler.scheduledThreadPool.shutdown();
    }


}
